#include "log.h"
#include <stdint.h>
#include "i2c.h"

extern UART_HandleTypeDef huart1;

int start_log_index = 0;
uint8_t start_transfer_flag = 0;

int get_log_index(uint8_t *count);
int write_log_index(uint8_t index, uint8_t count);

int get_str_len(char *msg)
{
    int len = 0;
    
    if (msg == NULL)
        return 0;
    
    while(*msg++ != '\0')
        len++;
    
    return len;
}

int mcu_log_write(char *msg)
{
    uint8_t index = 0;
    uint16_t dev_addr = 0;
    uint16_t msg_len  = 0;
    uint8_t count = 0;
    
    index = get_log_index(&count);
    msg_len = get_str_len(msg) + 1;
    
    if (index < 0 || index > EEPROM_I2C_PAGE_NUM - EEPROM_I2C_INDEX_PAGE)
        return -1;
    
    if (msg_len > EEPROM_I2C_PAGE_SIZE)
        return -1;
    
    dev_addr = (index + EEPROM_I2C_INDEX_PAGE) * EEPROM_I2C_PAGE_SIZE;
    
    HAL_I2C_Mem_Write(&hi2c2, EEPROM_I2C_WRITE_ADDR,
    dev_addr, I2C_MEMADD_SIZE_8BIT, (uint8_t *)msg, msg_len, 50);
    HAL_Delay(5);
    
    write_log_index(index, count + 1);
    return 0;
}

int write_log_index(uint8_t index, uint8_t count)
{
    HAL_I2C_Mem_Write(&hi2c2, EEPROM_I2C_WRITE_ADDR,
    index, I2C_MEMADD_SIZE_8BIT, &count,1,50);
    HAL_Delay(5);
    
    return 0;
}

int get_log_index(uint8_t *count)
{
    uint8_t arry[EEPROM_I2C_PAGE_NUM] = {0};
    int i = 0;
    uint8_t min = 0;
    uint8_t index = 0;
    HAL_StatusTypeDef status;
    
    status = HAL_I2C_Mem_Read(&hi2c2, EEPROM_I2C_READ_ADDR,
    0, I2C_MEMADD_SIZE_8BIT,arry, EEPROM_I2C_PAGE_NUM, 50);
    HAL_Delay(5);
    //get min index
    min = arry[0];
    for (i = 0 ; i < EEPROM_I2C_PAGE_NUM - EEPROM_I2C_INDEX_PAGE; i++)
    {
        if (min > arry[i])
        {
            min = arry[i];
            index = i;
        }
    }
    
    if (min == 0xFF) //count overrun 
    {
        min = 0;
        for (i = 0; i < EEPROM_I2C_PAGE_NUM; i++)
        {
            arry[i] = 0;
        }
        index = 0;
        
        for (i = 0; i < EEPROM_I2C_INDEX_PAGE; i++)
        {
            status = HAL_I2C_Mem_Write(&hi2c2, EEPROM_I2C_WRITE_ADDR,
            i * EEPROM_I2C_PAGE_SIZE, I2C_MEMADD_SIZE_8BIT,
            arry + i * EEPROM_I2C_PAGE_SIZE, EEPROM_I2C_PAGE_SIZE, 50);
            HAL_Delay(5);
            if (status != HAL_OK)
                break;
        }
    }
    *count = min;
    return (status == HAL_OK) ? index : -1;
}

// get start log index
void begin_send_log(void)
{
    uint8_t count = 0;
    
    start_log_index = get_log_index(&count);
    start_transfer_flag = 1;
}

// read single page 
int read_single_log(int index, uint8_t *data, uint8_t len)
{
    uint16_t dev_addr = 0;
    
    dev_addr = (index + EEPROM_I2C_INDEX_PAGE) * EEPROM_I2C_PAGE_SIZE;
    
    return HAL_I2C_Mem_Read(&hi2c2, EEPROM_I2C_READ_ADDR, dev_addr,
    I2C_MEMADD_SIZE_8BIT, data, len, 50);
}

void send_log_to_soc(void)
{
    static uint16_t send_count = 0;
    uint16_t index = 0;
    uint8_t data[EEPROM_I2C_PAGE_SIZE] = {0};
    int i = 0;
    
    //transfer 8 
    for (i = 0; i < 8; i++)
    {
        index = (start_log_index + 15 - send_count - 1) % 15;
        read_single_log(index,data,EEPROM_I2C_PAGE_SIZE);
        send_count++;
        HAL_UART_Transmit(&huart1,data,EEPROM_I2C_PAGE_SIZE,50);
        HAL_Delay(5);
        if (send_count >= EEPROM_I2C_PAGE_NUM - EEPROM_I2C_INDEX_PAGE)
        {
             send_count=0;
             start_transfer_flag = 0;
             break;
        }
    }
}

// reset eeprom with 0xff
void reset_eeprom(void)
{
    uint8_t data[EEPROM_I2C_PAGE_SIZE] = {0xff};
    int i = 0;
    uint32_t status;
    
    for (i = 0; i < EEPROM_I2C_PAGE_SIZE; i++)
        data[i] = 0xff;
    
    for (i = 0; i < 16; i++)
    {
         status = HAL_I2C_Mem_Write(&hi2c2, EEPROM_I2C_WRITE_ADDR,
            i * EEPROM_I2C_PAGE_SIZE, I2C_MEMADD_SIZE_8BIT,
            data, EEPROM_I2C_PAGE_SIZE, 50);
        
        if (status == HAL_OK)
            printf("Write EEPROM Success!\r\n");
        else
            printf("Write EEPROM Failed!\r\n");
        
        HAL_Delay(5);
    }
}

// print eeprom context
void print_eeprom(void)
{
    uint8_t data[16] = {0};
    int i = 0;
    int j = 0;
    uint32_t status = 0;
    
    // 16 * 16 = 256Bytes. print first 256Bytes
    for (i = 0; i < 16; i++)
    {
        status = HAL_I2C_Mem_Read(&hi2c2, EEPROM_I2C_READ_ADDR, i * 16,
        I2C_MEMADD_SIZE_8BIT, data, 16, 50);
        HAL_Delay(5);
       
        for (j = 0; j < 16; j++)
        {
            printf("0x%x ", data[j]);
        }
        printf("\r\n");
    }
}
